package com.tlgen.modules.system.service.impl;

import com.tlgen.common.exception.EntityExistException;
import com.tlgen.common.utils.FileUtil;
import com.tlgen.common.utils.PageUtil;
import com.tlgen.common.utils.QueryHelp;
import com.tlgen.common.utils.ValidationUtil;
import com.tlgen.modules.system.domain.Policy;
import com.tlgen.modules.system.domain.CSort;
import com.tlgen.modules.system.repository.PolicyRepository;
import com.tlgen.modules.system.service.PolicyService;
import com.tlgen.modules.system.service.dto.PolicyDto;
import com.tlgen.modules.system.service.dto.PolicyQueryCriteria;
import com.tlgen.modules.system.service.mapper.PolicyMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Service
@CacheConfig(cacheNames = "Policy")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PolicyServiceImpl implements PolicyService {

    private final PolicyRepository policyRepository;

    private final PolicyMapper policyMapper;

    public PolicyServiceImpl(PolicyRepository policyRepository, PolicyMapper policyMapper) {
        this.policyRepository = policyRepository;
        this.policyMapper = policyMapper;
    }


    /**
     * 不带条件分页查询
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(Pageable pageable) {
        return policyMapper.toDto(policyRepository.findAll(pageable).getContent());
    }


    /**
     * 带条件分页查询
     * @param criteria 条件
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(PolicyQueryCriteria criteria, Pageable pageable) {
        Page<Policy> page = policyRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(policyMapper::toDto));
    }

    /**
     * 带条件不分页查询
     * @param criteria 条件
     * @return
     */
    @Override
    @Cacheable
    public List<PolicyDto> queryAll(PolicyQueryCriteria criteria) {
        return policyMapper.toDto(policyRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    /**
     * 新增
     * @param resources /
     * @return
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public PolicyDto create(Policy resources) {
        if(policyRepository.findByDeductible(resources.getDeductible()) != null){
            throw new EntityExistException(Policy.class,"deductible",resources.getDeductible());
        }
        return policyMapper.toDto(policyRepository.save(resources));
    }

    /**
     * 编辑
     * @param resources /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Policy resources) {
        Policy Policy = policyRepository.findById(resources.getId()).orElseGet(Policy::new);
        ValidationUtil.isNull(Policy.getId(),"Policy","id",resources.getId());

        Policy Policy1 = policyRepository.findByDeductible(resources.getDeductible());

        if(Policy1 != null && !Policy1.getId().equals(Policy1.getId())){
            throw new EntityExistException(CSort.class,"Policy",resources.getDeductible());
        }

        Policy.setYear(resources.getYear());
        Policy.setDeductible(resources.getDeductible());
        Policy.setCapping(resources.getCapping());
        Policy.setRate(resources.getRate());
        policyRepository.save(Policy);
    }

    /**
     * 根据Id查询
     * @param id /
     * @return
     */
    @Override
    @Cacheable(key = "#p0")
    public PolicyDto findById(long id) {
        Policy Policy = policyRepository.findById(id).orElseGet(Policy::new);
        ValidationUtil.isNull(Policy.getId(),"Policy","id",id);
        return policyMapper.toDto(Policy);
    }

    /**
     * 删除
     * @param ids /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        for (Long id : ids) {
            policyRepository.deleteById(id);
        }
    }

    /**
     * 导出数据
     * @param response /
     * @throws IOException
     */
    @Override
    public void download(List<PolicyDto> PolicyDtos, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (PolicyDto PolicyDto : PolicyDtos) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("年度", PolicyDto.getYear());
            map.put("起付线", PolicyDto.getDeductible());
            map.put("封顶线", PolicyDto.getDeductible());
            map.put("报销比率", PolicyDto.getRate());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

}
